Block diagram notations may be used to design a multitude of systems that can be implemented in software, hardware, or a combination of the two. Examples of systems that can be designed using block diagrams are communication systems such as encoders/decoders, automotive control systems such as ABS or cruise controllers, avionic controllers, and many more. These block diagram notations require generating code for simulation. In the case where the system is implemented in software, code generation may also be required for execution in an embedded context such as in embedded software. Block diagrams are commonly used today for embedded software design and/or programming.
The performance of embedded software is typically measured by its system's throughput as well as by the required size of the program and data memory. Efficient analysis and treatment of the blocks increases the efficiency of the system. Each block represents a particular system function or actor. Depending upon the complexity of an actor, it could be itself represented by a number of sub-blocks. These blocks and sub-blocks can be symbolized as block diagrams. Block-diagram notations are useful for modeling different types of circuit designs.
Each block has a segment of program code associated with it, which when executed, implements the function in the system. Each block can execute (i.e., fire) at any time provided its requisite input data is available. These block diagram notations have a graphical syntax as well as some determined semantics.
Once a block-diagram is drawn, the diagram may be simulated in order to observe whether its behavior is as expected. Eventually, it is desirable to produce software that implements the diagram and execute this software in some application. This may be achieved by knowing how to generate code from a given diagram that implements the semantics of the diagram in a correct and efficient manner. Notice that simulation itself is one of the main applications of code generation: the software that implements the semantics of the diagram correctly and efficiently can be used to simulate the diagram.
Prior solutions to the code generation problem typically produce “flat” code: first, the diagram is “flattened” (i.e., remove its hierarchy to produce a diagram where all blocks are at the same level), and then, code for this flat diagram is generated. This process has a number of drawbacks. First, it involves the overhead of flattening which can be significant for a large diagram. Second, the hierarchical structure of the diagram is not preserved in the code, which means that the code is unstructured. The user has to also inspect, understand and modify the code, which is separate from the diagram. Third, modular code generation is not possible with the flattening method because the code is generated for a block depending on where this block is embedded and also what detailed knowledge is required for the sub-blocks. For example, if a block containing a sub-hierarchy is replicated twice in a diagram, the flattening procedure is typically unable to recognize this situation and will flatten the two identical blocks twice. It will also replicate the code generated for the replicated block, which means that the total generated code will be much larger and contain redundancy. Another drawback with “flattening” is that sub-blocks cannot be treated as “black boxes” during code generation, which causes intellectual property (IP), security and privacy issues.